package com.znh.common;

import com.znh.entity.GameRule;
import com.znh.entity.Ma;
import com.znh.entity.Piece;
import com.znh.enums.PiecePlayerEnum;

import java.awt.*;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @version 1.0
 * @Author znh
 * @Date 2024/5/28 上午10:54
 * @注释 工具类
 */
public class Utils {
    public static <T> T deepClone(T obj)  {
        //序列化
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream out = null;
        try {
            out = new ObjectOutputStream(bos);
            out.writeObject(obj);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //反序列化
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream in = null;
        T clone =null;
        try {
            in = new ObjectInputStream(bis);
            clone= (T) in.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return clone;
    }

    /**
     * 加载资源文件返回流
     * @param fileName
     * @return 文件流
     */
    public static InputStream readResourceFile(String fileName) {
        return Utils.class.getClassLoader().getResourceAsStream(fileName);
    }

    /**
     * 将局面生成一串字符串
     * 第1个数字表示阵营
     * 第2个数字表示棋子，帅(将)=1，仕(士)=2，相(象)=3，马=4，车=5，炮=6，兵(卒)=7
     * 第3个数字表示x坐标 从0开始
     * 第4个数字表示y坐标 从0开始
     *
     * @param phase 局面map
     * @return 局面字符串
     */
    public static String phaseToString(Map<Point, Piece> phase) {
        StringBuilder result = new StringBuilder();
        phase.forEach((point, piece) -> {
            result.append(piece.getPlayer().ordinal()).append(GameRule.PIECE_NAME_ANAME.get(piece.getName()))
                    .append(piece.getPoint().x - 1).append(piece.getPoint().y - 1);
        });
        return result.toString();
    }

    /**
     * 反转局面字符串
     * @param phase
     * @return 反转局面字符串
     */
    public static String phaseReverse(String phase){
        StringBuilder result=new StringBuilder();
        int start=phase.length()-1;
        int end=phase.length();
        while (start>=0){
            if (start%4==0){
                for (int i = start; i < end; i++) {
                    char c = phase.charAt(i);
                    if (i%4==2){
                        //x
                        c= (char) (8-(c-'0')+'0');
                    }else if (i%4==3){
                        //y
                        c= (char) (9-(c-'0')+'0');
                    }
                    result.append(c);
                }
                end=start;
            }
            start--;
        }
        return result.toString();
    }

    /**
     * 解析局面字符串
     *
     * @param phase
     * @return 坐标和对应的棋子（分红、黑）
     */
    public static Map<PiecePlayerEnum, Map<Point, String>> analysisPhasePointName(String phase) {
        HashMap<PiecePlayerEnum, Map<Point, String>> result = new HashMap();
        Map<Point, String> red = new HashMap<>();
        Map<Point, String> black = new HashMap<>();
        StringBuilder item = new StringBuilder();
        for (int i = 0; i < phase.length(); i++) {
            item.append(phase.charAt(i));
            if (item.length() == 4) {
                int player = item.charAt(0) - '0';   //红黑
                String aName = String.valueOf(item.charAt(1));     //棋子名称
                int x = item.charAt(2) - '0';        //棋子x坐标
                int y = item.charAt(3) - '0';        //棋子y坐标
                if (player == PiecePlayerEnum.RED.ordinal()) {
                    red.put(new Point(x + 1, y + 1), GameRule.PIECE_ANAME_NAME.get(aName));
                } else {
                    black.put(new Point(x + 1, y + 1), GameRule.PIECE_ANAME_NAME.get(aName));
                }
                item.setLength(0);
            }
        }
        result.put(PiecePlayerEnum.RED, red);
        result.put(PiecePlayerEnum.BLACK, black);
        return result;
    }


    /**
     * 反转逻辑坐标
     *
     * @param point 逻辑坐标
     */
    public static void reversePoint(Point point) {
        point.setLocation(10 - point.x, 11 - point.y);
    }

    /**
     * 反转局面
     * @param phase 局面map
     */
    public static void reversePhaseMap(Map<Point, Piece> phase) {
        //map的key值不能修改，一旦修改再get就是null，因为在put的时候会计算hashcode，根据hashcode来匹配
        //map不能在遍历的时候添加元素
        HashMap<Point, Piece> temp = new HashMap<>();
        phase.forEach((point, piece) -> {
            //由于key和value的point是同一个引用，不需要翻转key，不然会造成两次翻转
//            Utils.reversePoint(point);
            piece.reversePoint();
            temp.put(point, piece);
        });
        phase.clear();
        phase.putAll(temp);
    }

}
